package cn.iocoder.yudao.module.game.controller.app;

import cn.hutool.json.JSONObject;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.module.game.controller.admin.gameLog.vo.GameLogSaveReqVO;
import cn.iocoder.yudao.module.game.controller.admin.gameToken.vo.GameTokenSaveReqVO;
import cn.iocoder.yudao.module.game.controller.app.vo.RealPGResult;
import cn.iocoder.yudao.module.game.dal.dataobject.gameToken.GameTokenDO;
import cn.iocoder.yudao.module.game.service.gameLog.GameLogService;
import cn.iocoder.yudao.module.game.service.gameToken.GameTokenService;
import cn.iocoder.yudao.module.game.service.otherGame.RPGService;
import cn.iocoder.yudao.module.game.service.otherGame.TADAService;
import cn.iocoder.yudao.module.game.service.rechargerecord.RechargeRecordService;
import cn.iocoder.yudao.module.game.utils.AESEncrypt;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
import cn.iocoder.yudao.module.member.service.level.MemberLevelService;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.enums.UserTypeEnum.MEMBER;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "用户 APP - 用户收件地址")
@RestController
@RequestMapping("/game/pg")
@Validated
public class AppRealpgController {

    @Resource
    private RPGService rpgService;
    @Resource
    private GameLogService gameLogService;

    @Resource
    private MemberUserService memberUserService;
    @Resource
    private PayWalletService payWalletService;
    @Resource
    private PayWalletTransactionService payWalletTransactionService;
    @Resource
    private MemberLevelService memberlevelService;


    @PostMapping("/getGame")
    @Operation(summary = "创建用户收件地址")
    public CommonResult<String> getGame(@RequestBody Map<String, Object> params) throws Exception {
        params.put("token", rpgService.getToken(params.get("userId").toString()));
        return success(rpgService.login(params));
    }

    @PostMapping("/VerifySession")
    @Operation(summary = "创建用户收件地址")
    public RealPGResult VerifySession(@RequestParam Map<String, Object> body) throws Exception {
        createLog(0L, body);
        GameTokenDO gameTokenDO = rpgService.checkToken(body);
        if (gameTokenDO == null) {
            return new RealPGResult("1034", "无效请求");
        }

        MemberUserDO memberUserDO = memberUserService.getUser(gameTokenDO.getMemberId());
        Map<String, Object> res = new HashMap<>();
        res.put("player_name", memberUserDO.getId());
        res.put("nickname", memberUserDO.getMobile());
        res.put("currency", "BRL");
        return new RealPGResult(res);
    }

    @PostMapping("/Cash/Get")
    @Operation(summary = "更新用户收件地址")
    public RealPGResult getCash(@RequestParam Map<String, Object> body) throws Exception {
        createLog(0L, body);
        GameTokenDO gameTokenDO = rpgService.checkToken(body);
        if (gameTokenDO == null) {
            return new RealPGResult("1034", "无效请求");
        }

        PayWalletDO payWalletDO = payWalletService.getOrCreateWallet(Long.valueOf(body.get("player_name").toString()), MEMBER.getValue());

        Map<String, Object> res = new HashMap<>();
        res.put("currency_code", "BRL");
        res.put("balance_amount", new BigDecimal(payWalletDO.getBalance()).divide(new BigDecimal(100000), 2, RoundingMode.HALF_UP));
        res.put("updated_time", System.currentTimeMillis());
        return new RealPGResult(res);
    }

    @PostMapping("/Cash/TransferInOut")
    @Operation(summary = "更新用户收件地址")
    public RealPGResult transferInOutCash(@RequestParam Map<String, Object> body) throws Exception {
        Map<String, Object> bonus = new HashMap<>();
        bonus.put("5", 50);
        bonus.put("10", 50);
        bonus.put("15", 50);
        bonus.put("20", 50);
        bonus.put("25", 50);
        bonus.put("30", 50);
        bonus.put("40", 100);
        bonus.put("50", 100);
        bonus.put("60", 100);
        bonus.put("70", 100);
        bonus.put("80", 100);
        bonus.put("90", 100);
        bonus.put("100", 100);
        bonus.put("150", 500);
        bonus.put("200", 500);
        bonus.put("250", 500);
        bonus.put("300", 500);
        bonus.put("350", 500);
        bonus.put("400", 500);
        bonus.put("450", 500);
        bonus.put("500", 500);
        bonus.put("600", 1000);
        bonus.put("700", 1000);
        bonus.put("800", 1000);
        bonus.put("900", 1000);
        bonus.put("1000", 1000);
        bonus.put("1500", 5000);
        bonus.put("2000", 5000);
        bonus.put("2500", 5000);
        bonus.put("3000", 5000);
        bonus.put("4000", 10000);
        bonus.put("5000", 10000);
        bonus.put("6000", 10000);
        bonus.put("7000", 10000);
        bonus.put("8000", 10000);
        bonus.put("9000", 10000);
        bonus.put("10000", 10000);

        createLog(0L, body);
        GameTokenDO gameTokenDO = rpgService.checkToken(body);
        if (gameTokenDO == null) {
            return new RealPGResult("1034", "无效请求");
        }

        createLog(gameTokenDO.getMemberId(), body);

        PayWalletDO payWalletDO = payWalletService.getOrCreateWallet(Long.valueOf(body.get("player_name").toString()), MEMBER.getValue());
        payWalletService.reduceWalletBalance(payWalletDO.getId(),
                body.get("parent_bet_id").toString(),
                PayWalletBizTypeEnum.BET,
                (long)(Double.parseDouble(body.get("bet_amount").toString()) * 100000));
        payWalletService.addWalletBalance(payWalletDO.getId(),
                body.get("parent_bet_id").toString(),
                PayWalletBizTypeEnum.WIN,
                (long)(Double.parseDouble(body.get("win_amount").toString()) * 100000));

        MemberUserDO memberUserDO = memberUserService.getUser(Long.valueOf(body.get("player_name").toString()));

        memberlevelService.addExperience(memberUserDO.getId(),
                (long)(Double.parseDouble(body.get("bet_amount").toString())),
                MemberExperienceBizTypeEnum.ORDER_GIVE,
                body.get("parent_bet_id").toString());

        List<PayWalletTransactionDO> payWalletTransactionDOS =  payWalletTransactionService.list(memberUserDO.getCode(), PayWalletBizTypeEnum.RECHARGE.getType());
        String sumP =  payWalletTransactionService.betSum(memberUserDO.getCode(), PayWalletBizTypeEnum.BET.getType(), 0).get("sum_p").toString();

        MemberUserDO fReferrerUser = memberUserService.getUserByReferrer(memberUserDO.getReferrer());
        if (fReferrerUser != null) {
            if (payWalletTransactionDOS.size() > 0 && (payWalletTransactionDOS.get(0).getPrice() / 100000) >= 20 && Long.valueOf(sumP) >= 50 && memberUserDO.getReferrerStatus().equals(0)) {
                if (bonus.get(String.valueOf(fReferrerUser.getQualifiedNum() + 1)) != null) {
                    payWalletService.addWalletBalance(payWalletDO.getId(),
                            body.get("parent_bet_id").toString(),
                            PayWalletBizTypeEnum.GENERALIZATION_COMMISSION,
                            (long)(Double.parseDouble(bonus.get(String.valueOf(fReferrerUser.getQualifiedNum() + 1)).toString()) * 100000));
                }

                MemberUserUpdateReqVO memberUserUpdateReqVO = new MemberUserUpdateReqVO();
                memberUserUpdateReqVO.setReferrerStatus(1);
                memberUserUpdateReqVO.setQualifiedNum(fReferrerUser.getQualifiedNum() + 1);
                memberUserUpdateReqVO.setId(fReferrerUser.getId());
                memberUserService.updateUser(memberUserUpdateReqVO);
            }

            PayWalletDO fReferrerPayWalletDO = payWalletService.getOrCreateWallet(fReferrerUser.getId(), UserTypeEnum.MEMBER.getValue());
            payWalletService.addWalletBalance(fReferrerPayWalletDO.getId(),
                    body.get("parent_bet_id").toString(),
                    PayWalletBizTypeEnum.BET_COMMISSION,
                    (long)(Double.parseDouble(body.get("bet_amount").toString()) * 100000 * 0.03 / 100));

            MemberUserDO sReferrerUser = memberUserService.getUserByReferrer(fReferrerUser.getReferrer());
            if (sReferrerUser != null) {
                PayWalletDO sReferrerPayWalletDO = payWalletService.getOrCreateWallet(sReferrerUser.getId(), UserTypeEnum.MEMBER.getValue());
                payWalletService.addWalletBalance(sReferrerPayWalletDO.getId(),
                        body.get("parent_bet_id").toString(),
                        PayWalletBizTypeEnum.BET_COMMISSION,
                        (long)(Double.parseDouble(body.get("bet_amount").toString()) * 100000 * 0.01 / 100));

            }
        }

        payWalletDO = payWalletService.getOrCreateWallet(Long.valueOf(body.get("player_name").toString()), MEMBER.getValue());

        Map<String, Object> res = new HashMap<>();
        res.put("currency_code", "BRL");
        res.put("balance_amount", new BigDecimal(payWalletDO.getBalance()).divide(new BigDecimal(100000), 2, RoundingMode.HALF_UP));
        res.put("updated_time", System.currentTimeMillis());
        return new RealPGResult(res);
    }

    private void createLog(Long memberId, Map<String, Object> params) {

        String result = params.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining(", "));

        GameLogSaveReqVO createReqVO = new GameLogSaveReqVO();
        createReqVO.setRemark(result);
        if (memberId.equals(0L)) {
            gameLogService.createLog(createReqVO);
            return;
        }
        createReqVO.setMemberId(memberId);
        createReqVO.setGameId(Long.valueOf(params.get("game_id").toString()));
//        createReqVO.setPreChangeCoin(new BigDecimal(params.get("transfer_amount").toString()));
        createReqVO.setOpeCoin(new BigDecimal(params.get("transfer_amount").toString()));
        gameLogService.createLog(createReqVO);
    }

}
